﻿#include "db_api_.h"

DBCONTENT * hDB = 0;

int _db_init(db_cb cb, get_sd_status cb_get_sd_status)
{
	OAL_QUEUE_POOL pool = {sizeof(DBMSG) * 1};

	hDB = (DBCONTENT*)OAL_malloc(sizeof(DBCONTENT));
	if(hDB == 0)
	{
		return -1;
	}

	memset(hDB, 0, sizeof(DBCONTENT));

	hDB->cb = cb;
	hDB->cb_get_sd_status = cb_get_sd_status;

	hDB->mutex = OAL_mutex_create();
	if(hDB->mutex == 0)
	{
		return -1;
	}

	if(OAL_SUCCESS != OAL_queue_create(&hDB->q_to_task, (char*)"to task", sizeof(DBMSG), &pool))
	{
		hDB->q_to_task = (void*)0;
		return -1;
	}

	if(OAL_SUCCESS != OAL_queue_create(&hDB->q_fm_task, (char*)"from task", sizeof(DBMSG), &pool))
	{
		hDB->q_fm_task = (void*)0;
		return -1;
	}

	hDB->task = OAL_thread_create(db_task, 0, (char *)"db_task", OAL_THREAD_PRIORITY_LOW, 3072);
	if(hDB->task == 0)
	{
		return -1;
	}
	
	hDB->state = 0;

	return _db_mount();
}

void _db_free()
{
	if(hDB)
	{
		if(hDB->task)
		{
			DBMSG msg;
			msg.id = MSGID_QUIT;
			OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER);
			OAL_thread_join(hDB->task);
			hDB->task = (void*)0;
		}
		
		if(hDB->q_to_task)
		{
			OAL_queue_delete(&hDB->q_to_task);
			hDB->q_to_task = (void*)0;
		}

		if(hDB->q_fm_task)
		{
			OAL_queue_delete(&hDB->q_fm_task);
			hDB->q_fm_task = (void*)0;
		}

		if(hDB->mutex)
		{
			OAL_mutex_destroy(&hDB->mutex);
			hDB->mutex = 0;
		}

		db_ffclose(&hDB->f_record);
		db_ffclose(&hDB->f_record_new);
		db_ffclose(&hDB->f_index);

		if (hDB->idbuf)
		{
			OAL_free(hDB->idbuf);
			hDB->idbuf = 0;
		}

		OAL_free(hDB);
		hDB = 0;
	}
}

int _db_reset(void)
{
	DBMSG msg;
	msg.id = MSGID_DB_RESET;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_get_state(void)	//获取数据库状态；-1=数据库未初始化；0=unmount；1=构建中；2=就绪，应用可以访问。-2=数据库出错
{
	DBMSG msg;
	msg.id = MSGID_GET_STATE;
	msg.u.read.str = 0;
	msg.u.read.type_like = 0;
	msg.u.read.offset = 0;
	msg.u.read.records = 0;
	msg.u.read.fname = 0;
	msg.u.read.albums = 0;
	msg.u.read.artists = 0;
	msg.u.read.cnt = 0;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_mount(void)
{
	DBMSG msg;
	msg.id = MSGID_MOUNT;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_unmount(void)
{
	DBMSG msg;
	msg.id = MSGID_UNMOUNT;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_set_like(char * path, int like)
{
	DBMSG msg;
	msg.id = MSGID_SET_LIKE;
	msg.u.write.path = path;
	msg.u.write.like = like;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_delete_file(char * path)
{
	DBMSG msg;
	msg.id = MSGID_DELETE_FILE;
	msg.u.write.path = path;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_add_wave(char * path)
{
	DBMSG msg;
	msg.id = MSGID_ADD_WAVE;
	msg.u.write.path = path;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_add_tag(
	char * path,			// 文件名；类型是 MEDIA_HI_TEXT / MEDIA_HI_AUDIO / MEDIA_HI_WAVE
	unsigned int No,		// 标签序号
	unsigned int tag		// 标签值
	)						// 返回-1表示出错；0=OK
{
	DBMSG msg;
	msg.id = MSGID_ADD_TAG;
	msg.u.write.path = path;
	msg.u.write.like = No;
	msg.u.write.tag = tag;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_read_type(
	unsigned int type,		// MEDIA_HI_TEXT / MEDIA_HI_IMAGE / MEDIA_HI_AUDIO / MEDIA_HI_VIDEO / MEDIA_HI_WAVE
	unsigned int offset,	// 偏移值
	RECORD * records,		// 输出的记录指针，0=不输出记录信息
	RECITEMUTF8 * fname,	// 输出的utf8文件名指针，0=不输出文件名
	unsigned int cnt		// 请求的记录个数
	)						// 返回读取到的记录个数，-1表示出错；参数全0（type除外）返回该type的总个数
{
	DBMSG msg;
	msg.id = MSGID_READ_TYPE;
	msg.u.read.str = 0;
	msg.u.read.type_like = type;
	msg.u.read.offset = offset;
	msg.u.read.records = records;
	msg.u.read.fname = fname;
	msg.u.read.albums = 0;
	msg.u.read.artists = 0;
	msg.u.read.cnt = cnt;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_read_like(
	int like,				// 喜欢号，1-32之间
	unsigned int offset,	// 偏移值
	RECORD * records,		// 输出的记录指针，0=不输出记录信息
	RECITEMUTF8 * fname,	// 输出的utf8文件名指针，0=不输出文件名
	unsigned int cnt		// 请求的记录个数
	)						// 返回读取到的记录个数，-1表示出错；参数全0（like除外）返回该like的总个数
{
	DBMSG msg;
	msg.id = MSGID_READ_LIKE;
	msg.u.read.str = 0;
	msg.u.read.type_like = like;
	msg.u.read.offset = offset;
	msg.u.read.records = records;
	msg.u.read.fname = fname;
	msg.u.read.albums = 0;
	msg.u.read.artists = 0;
	msg.u.read.cnt = cnt;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_read_folder(
	char * dir,				// 目录名
	unsigned int offset,	// 偏移值
	RECORD * records,		// 输出的记录指针，0=不输出记录信息
	RECITEMUTF8 * fname,	// 输出的utf8文件名指针，0=不输出文件名
	unsigned int cnt		// 请求的记录个数
	)						// 返回读取到的记录个数，-1表示出错；参数全0（dir除外）返回该dir的总个数；如果dir也填0，则返回所有目录的个数
{
	DBMSG msg;
	msg.id = MSGID_READ_FOLDER;
	msg.u.read.str = dir;
	msg.u.read.type_like = 0;
	msg.u.read.offset = offset;
	msg.u.read.records = records;
	msg.u.read.fname = fname;
	msg.u.read.albums = 0;
	msg.u.read.artists = 0;
	msg.u.read.cnt = cnt;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_read_pl(
	char * dir,				// 目录名
	unsigned int offset,	// 偏移值
	RECORD * records,		// 输出的记录指针，0=不输出记录信息
	RECITEMUTF8 * fname,	// 输出的utf8文件名指针，0=不输出文件名
	unsigned int cnt		// 请求的记录个数
	)						// 返回读取到的记录个数，-1表示出错；参数全0（dir除外）返回该dir的总个数；如果dir也填0，则返回所有目录的个数
{
	DBMSG msg;
	msg.id = MSGID_READ_PL;
	msg.u.read.str = dir;
	msg.u.read.type_like = 0;
	msg.u.read.offset = offset;
	msg.u.read.records = records;
	msg.u.read.fname = fname;
	msg.u.read.albums = 0;
	msg.u.read.artists = 0;
	msg.u.read.cnt = cnt;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_read_albums(		// 读取所有专辑名称
	unsigned int offset,	// 偏移值
	RECITEMUTF8 * albums,	// 输出的utf8专辑名指针，0=不输出专辑名, 只查询专辑个数
	unsigned int cnt		// 请求的记录个数
	)						// 返回读取到的记录个数，-1表示出错；
{
	DBMSG msg;
	msg.id = MSGID_READ_ALBUMS;
	msg.u.read.str = 0;
	msg.u.read.type_like = 0;
	msg.u.read.offset = offset;
	msg.u.read.records = 0;
	msg.u.read.fname = 0;
	msg.u.read.albums = albums;
	msg.u.read.artists = 0;
	msg.u.read.cnt = cnt;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_read_audio_by_album(
	char * album,			// 输入参数，非空的专辑名，utf8格式
	unsigned int offset,	// 偏移值
	RECORD * records,		// 输出的记录指针，0=不输出记录信息
	RECITEMUTF8 * fname,	// 输出的utf8文件名指针，0=不输出文件名
	unsigned int cnt		// 请求的记录个数
	)						// 返回读取到的记录个数，-1表示出错；如果records和fname均为0，则返回该专辑的所有歌曲的个数
{
	DBMSG msg;
	msg.id = MSGID_READ_AUDIO_BY_ALBUM;
	msg.u.read.str = album;
	msg.u.read.type_like = 0;
	msg.u.read.offset = offset;
	msg.u.read.records = records;
	msg.u.read.fname = fname;
	msg.u.read.albums = 0;
	msg.u.read.artists = 0;
	msg.u.read.cnt = cnt;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_read_album(
	char * album,			// 专辑名，utf8格式
	unsigned int offset,	// 偏移值
	RECORD * records,		// 输出的记录指针，0=不输出记录信息
	RECITEMUTF8 * fname,	// 输出的utf8文件名指针，0=不输出文件名
	RECITEMUTF8 * albums,	// 输出的utf8专辑名指针，0=不输出专辑名
	unsigned int cnt		// 请求的记录个数
	)						// 返回读取到的记录个数，-1表示出错；参数全0（album除外）返回该album的歌曲的总个数；如果album也填0，则返回所有album的个数
							// 特别说明：album为空，查询所有专辑名称信息，此时不理会records和fname指针。当指针albums非空，取回专辑名称列表
							// 特别说明：album非空，查询指定专辑的音乐文件信息，此时不理会albums指针。当指针records和fname其中一个不为空，取回该专辑音乐相应的字段信息
{
	DBMSG msg;
	msg.id = MSGID_READ_ALBUM;
	msg.u.read.str = album;
	msg.u.read.type_like = 0;
	msg.u.read.offset = offset;
	msg.u.read.records = records;
	msg.u.read.fname = fname;
	msg.u.read.albums = albums;
	msg.u.read.artists = 0;
	msg.u.read.cnt = cnt;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_read_artists(		// 读取所有专辑名称
	unsigned int offset,	// 偏移值
	RECITEMUTF8 * artists,	// 输出的utf8专辑名指针，0=不输出专辑名, 只查询专辑个数
	unsigned int cnt		// 请求的记录个数
	)						// 返回读取到的记录个数，-1表示出错；
{
	DBMSG msg;
	msg.id = MSGID_READ_ARTISTS;
	msg.u.read.str = 0;
	msg.u.read.type_like = 0;
	msg.u.read.offset = offset;
	msg.u.read.records = 0;
	msg.u.read.fname = 0;
	msg.u.read.albums = 0;
	msg.u.read.artists = artists;
	msg.u.read.cnt = cnt;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_read_audio_by_artist(
	char * artist,			// 输入参数，非空的专辑名，utf8格式
	unsigned int offset,	// 偏移值
	RECORD * records,		// 输出的记录指针，0=不输出记录信息
	RECITEMUTF8 * fname,	// 输出的utf8文件名指针，0=不输出文件名
	unsigned int cnt		// 请求的记录个数
	)						// 返回读取到的记录个数，-1表示出错；如果records和fname均为0，则返回该专辑的所有歌曲的个数
{
	DBMSG msg;
	msg.id = MSGID_READ_AUDIO_BY_ARTIST;
	msg.u.read.str = artist;
	msg.u.read.type_like = 0;
	msg.u.read.offset = offset;
	msg.u.read.records = records;
	msg.u.read.fname = fname;
	msg.u.read.albums = 0;
	msg.u.read.artists = 0;
	msg.u.read.cnt = cnt;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}

int _db_read_artist(
	char * artist,			// 艺术家名，utf8格式
	unsigned int offset,	// 偏移值
	RECORD * records,		// 输出的记录指针，0=不输出记录信息
	RECITEMUTF8 * fname,	// 输出的utf8文件名指针，0=不输出文件名
	RECITEMUTF8 * artists,	// 输出的utf8专辑名指针，0=不输出专辑名
	unsigned int cnt		// 请求的记录个数
	)						// 返回读取到的记录个数，-1表示出错；参数全0（artist除外）返回该artist的歌曲的总个数；如果artist也填0，则返回所有artist的个数
							// 特别说明：artist为空，查询所有歌手名称信息，此时不理会records和fname指针。当指针albums非空，取回歌手名称列表
							// 特别说明：artist非空，查询指定歌手的音乐文件信息，此时不理会artists指针。当指针records和fname其中一个不为空，取回该专辑音乐相应的字段信息
{
	DBMSG msg;
	msg.id = MSGID_READ_ARTIST;
	msg.u.read.str = artist;
	msg.u.read.type_like = 0;
	msg.u.read.offset = offset;
	msg.u.read.records = records;
	msg.u.read.fname = fname;
	msg.u.read.albums = 0;
	msg.u.read.artists = artists;
	msg.u.read.cnt = cnt;
	if(OAL_SUCCESS != OAL_queue_send(&hDB->q_to_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	if(OAL_SUCCESS != OAL_queue_recv(&hDB->q_fm_task, &msg, OAL_WAIT_FOREVER))
	{
		return -1;
	}
	return msg.u.reponse.res;
}
